🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / core / service / src / commonTest / kotlin / org / meshtastic / core / service / RadioControllerImplTest.kt
Displaying Raw • Download
core/service/src/commonTest/kotlin/org/meshtastic/core/service/RadioControllerImplTest.kt b137a7f9ebb00561913b69880ff4ca21c688bdf1 (b137a7f9) Text, 21.45 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.service
Tff7b72import T7ee787dev.mokkery.MockMode
Tff7b72import T7ee787dev.mokkery.answering.calls
Tff7b72import T7ee787dev.mokkery.answering.returns
Tff7b72import T7ee787dev.mokkery.every
Tff7b72import T7ee787dev.mokkery.everySuspend
Tff7b72import T7ee787dev.mokkery.matcher.any
Tff7b72import T7ee787dev.mokkery.mock
Tff7b72import T7ee787dev.mokkery.verify
Tff7b72import T7ee787dev.mokkery.verify.VerifyMode.Companion.atLeast
Tff7b72import T7ee787dev.mokkery.verify.VerifyMode.Companion.exactly
Tff7b72import T7ee787dev.mokkery.verifySuspend
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableStateFlow
Tff7b72import T7ee787kotlinx.coroutines.test.TestScope
Tff7b72import T7ee787kotlinx.coroutines.test.advanceUntilIdle
Tff7b72import T7ee787kotlinx.coroutines.test.runTest
Tff7b72import T7ee787org.meshtastic.core.common.database.DatabaseManager
Tff7b72import T7ee787org.meshtastic.core.model.ConnectionState
Tff7b72import T7ee787org.meshtastic.core.model.DataPacket
Tff7b72import T7ee787org.meshtastic.core.model.Node
Tff7b72import T7ee787org.meshtastic.core.model.NodeAddress
Tff7b72import T7ee787org.meshtastic.core.repository.CommandSender
Tff7b72import T7ee787org.meshtastic.core.repository.MeshDataHandler
Tff7b72import T7ee787org.meshtastic.core.repository.MeshLocationManager
Tff7b72import T7ee787org.meshtastic.core.repository.MeshMessageProcessor
Tff7b72import T7ee787org.meshtastic.core.repository.MeshPrefs
Tff7b72import T7ee787org.meshtastic.core.repository.NodeManager
Tff7b72import T7ee787org.meshtastic.core.repository.NodeRepository
Tff7b72import T7ee787org.meshtastic.core.repository.NotificationManager
Tff7b72import T7ee787org.meshtastic.core.repository.PacketRepository
Tff7b72import T7ee787org.meshtastic.core.repository.PlatformAnalytics
Tff7b72import T7ee787org.meshtastic.core.repository.RadioConfigRepository
Tff7b72import T7ee787org.meshtastic.core.repository.RadioInterfaceService
Tff7b72import T7ee787org.meshtastic.core.repository.ServiceRepository
Tff7b72import T7ee787org.meshtastic.core.repository.UiPrefs
Tff7b72import T7ee787org.meshtastic.proto.AdminMessage
Tff7b72import T7ee787org.meshtastic.proto.Channel
Tff7b72import T7ee787org.meshtastic.proto.ChannelSettings
Tff7b72import T7ee787org.meshtastic.proto.ClientNotification
Tff7b72import T7ee787org.meshtastic.proto.Config
Tff7b72import T7ee787org.meshtastic.proto.HamParameters
Tff7b72import T7ee787org.meshtastic.proto.LocalConfig
Tff7b72import T7ee787org.meshtastic.proto.SharedContact
Tff7b72import T7ee787org.meshtastic.proto.User
Tff7b72import T7ee787kotlin.test.Test
Tff7b72import T7ee787kotlin.test.assertEquals
Tff7b72import T7ee787kotlin.test.assertNull
Tff7b72import T7ee787kotlin.test.assertSame
Tff7b72import T7ee787kotlin.test.assertTrue
Tff7b72class T56d364RadioControllerImplTest Tb4b4b4{
Tff7b72private Tff7b72val Te6edf3nodeRepositoryTb4b4b4: Te6edf3NodeRepository Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3commandSenderTb4b4b4: Te6edf3CommandSender Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3nodeManagerTb4b4b4: Te6edf3NodeManager Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3radioInterfaceServiceTb4b4b4: Te6edf3RadioInterfaceService Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3locationManagerTb4b4b4: Te6edf3MeshLocationManager Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3packetRepositoryTb4b4b4: Te6edf3PacketRepository Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3dataHandlerTb4b4b4: Te6edf3MeshDataHandler Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3analyticsTb4b4b4: Te6edf3PlatformAnalytics Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3meshPrefsTb4b4b4: Te6edf3MeshPrefs Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3uiPrefsTb4b4b4: Te6edf3UiPrefs Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3databaseManagerTb4b4b4: Te6edf3DatabaseManager Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3notificationManagerTb4b4b4: Te6edf3NotificationManager Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3messageProcessorTb4b4b4: Te6edf3MeshMessageProcessor Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3radioConfigRepositoryTb4b4b4: Te6edf3RadioConfigRepository Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3testScope Tff7b72= Te6edf3TestScopeTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72fun Td2a8ffcreateControllerTb4b4b4(
Te6edf3serviceRepositoryTb4b4b4: Te6edf3ServiceRepository Tff7b72= Te6edf3ServiceRepositoryImplTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3myNodeNumTb4b4b4: Tffa657Int? Tff7b72= T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3RadioControllerImpl Tb4b4b4{
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3myNodeNum Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3myNodeNumTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3myDeviceId Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72nullTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddress Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72nullTb4b4b4)
Tff7b72return Te6edf3RadioControllerImplTb4b4b4(
Te6edf3serviceRepository Tff7b72= Te6edf3serviceRepositoryTb4b4b4,
Te6edf3nodeRepository Tff7b72= Te6edf3nodeRepositoryTb4b4b4,
Te6edf3commandSender Tff7b72= Te6edf3commandSenderTb4b4b4,
Te6edf3nodeManager Tff7b72= Te6edf3nodeManagerTb4b4b4,
Te6edf3radioInterfaceService Tff7b72= Te6edf3radioInterfaceServiceTb4b4b4,
Te6edf3locationManager Tff7b72= Te6edf3locationManagerTb4b4b4,
Te6edf3packetRepository Tff7b72= Te6edf3lazy Tb4b4b4{ Te6edf3packetRepository Tb4b4b4}Tb4b4b4,
Te6edf3dataHandler Tff7b72= Te6edf3lazy Tb4b4b4{ Te6edf3dataHandler Tb4b4b4}Tb4b4b4,
Te6edf3analytics Tff7b72= Te6edf3analyticsTb4b4b4,
Te6edf3meshPrefs Tff7b72= Te6edf3meshPrefsTb4b4b4,
Te6edf3uiPrefs Tff7b72= Te6edf3uiPrefsTb4b4b4,
Te6edf3databaseManager Tff7b72= Te6edf3databaseManagerTb4b4b4,
Te6edf3notificationManager Tff7b72= Te6edf3notificationManagerTb4b4b4,
Te6edf3messageProcessor Tff7b72= Te6edf3lazy Tb4b4b4{ Te6edf3messageProcessor Tb4b4b4}Tb4b4b4,
Te6edf3radioConfigRepository Tff7b72= Te6edf3radioConfigRepositoryTb4b4b4,
Te6edf3scope Tff7b72= Te6edf3testScopeTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffconnectionStateAndClientNotificationDelegateToServiceRepositoryTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3serviceRepository Tff7b72= Te6edf3ServiceRepositoryImplTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3serviceRepository Tff7b72= Te6edf3serviceRepositoryTb4b4b4)
Tff7b72val Te6edf3notification Tff7b72= Te6edf3ClientNotificationTb4b4b4(Tb4b4b4)
Te6edf3assertSameTb4b4b4(Te6edf3serviceRepositoryTb4b4b4.Te6edf3connectionStateTb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3connectionStateTb4b4b4)
Te6edf3assertSameTb4b4b4(Te6edf3serviceRepositoryTb4b4b4.Te6edf3clientNotificationTb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3clientNotificationTb4b4b4)
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setConnectionStateTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectingTb4b4b4)
Te6edf3serviceRepositoryTb4b4b4.Te6edf3setClientNotificationTb4b4b4(Te6edf3notificationTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectingTb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3connectionStateTb4b4b4.Te6edf3valueTb4b4b4)
Te6edf3assertSameTb4b4b4(Te6edf3notificationTb4b4b4, Te6edf3controllerTb4b4b4.Te6edf3clientNotificationTb4b4b4.Te6edf3valueTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3clearClientNotificationTb4b4b4(Tb4b4b4)
Te6edf3assertNullTb4b4b4(Te6edf3serviceRepositoryTb4b4b4.Te6edf3clientNotificationTb4b4b4.Te6edf3valueTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsendMessageDelegatesToCommandSenderTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4)
Tff7b72val Te6edf3packet Tff7b72= Te6edf3DataPacketTb4b4b4(Te6edf3to Tff7b72= Te6edf3NodeAddressTb4b4b4.Te6edf3ID_BROADCASTTb4b4b4, Te6edf3channel Tff7b72= T79c0ff1Tb4b4b4, Te6edf3text Tff7b72= Ta5d6ff"Ta5d6ffpingTa5d6ff"Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3sendMessageTb4b4b4(Te6edf3packetTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3packetTb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{ Te6edf3dataHandlerTb4b4b4.Te6edf3rememberDataPacketTb4b4b4(Te6edf3packetTb4b4b4, T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Tff7b72falseTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsendSharedContactCallsCommandSenderAdminAwaitTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3nodeNum Tff7b72= T79c0ff3T79c0ff2T79c0ff1
Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Te6edf3NodeAddressTb4b4b4.Te6edf3numToDefaultIdTb4b4b4(Te6edf3nodeNumTb4b4b4)Tb4b4b4, Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffRemote NodeTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffRNTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= Te6edf3nodeNumTb4b4b4, Te6edf3user Tff7b72= Te6edf3userTb4b4b4, Te6edf3manuallyVerified Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeRepositoryTb4b4b4.Te6edf3getNodeTb4b4b4(Te6edf3NodeAddressTb4b4b4.Te6edf3numToDefaultIdTb4b4b4(Te6edf3nodeNumTb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3node
Te6edf3everySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminAwaitTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Tff7b72true
Tff7b72val Te6edf3result Tff7b72= Te6edf3controllerTb4b4b4.Te6edf3sendSharedContactTb4b4b4(Te6edf3nodeNumTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3resultTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminAwaitTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffrequestConfigOperationsDelegateToCommandSenderTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3getOwnerTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff1Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff1Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3getConfigTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff2Tb4b4b4, Te6edf3configType Tff7b72= T79c0ff2Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff3Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3getModuleConfigTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff3Tb4b4b4, Te6edf3moduleConfigType Tff7b72= T79c0ff4Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff5Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3getChannelTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff4Tb4b4b4, Te6edf3index Tff7b72= T79c0ff6Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff7Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3getRingtoneTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff5Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff8Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3getCannedMessagesTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff6Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff9Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3getDeviceConnectionStatusTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff7Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff1T79c0ff0Tb4b4b4)
T8b949e// All delegate to commandSender.sendAdmin
Te6edf3verifySuspendTb4b4b4(Te6edf3atLeastTb4b4b4(T79c0ff7Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffstopProvideLocationDelegatesToLocationManagerTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3stopProvideLocationTb4b4b4(Tb4b4b4)
Te6edf3verify Tb4b4b4{ Te6edf3locationManagerTb4b4b4.Te6edf3stopTb4b4b4(Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetDeviceAddressSwitchesDatabaseAndTransportTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddress Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Ta5d6ff"Ta5d6ffold:addrTa5d6ff"Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setDeviceAddressTb4b4b4(Ta5d6ff"Ta5d6fftcp:192.168.1.1Ta5d6ff"Tb4b4b4)
Te6edf3testScopeTb4b4b4.Te6edf3advanceUntilIdleTb4b4b4(Tb4b4b4)
T8b949e// Verify ordering: switchDevice completes before transport reconfiguration
Te6edf3verifySuspend Tb4b4b4{ Te6edf3meshPrefsTb4b4b4.Te6edf3setDeviceAddressTb4b4b4(Ta5d6ff"Ta5d6fftcp:192.168.1.1Ta5d6ff"Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{ Te6edf3databaseManagerTb4b4b4.Te6edf3switchActiveDatabaseTb4b4b4(Ta5d6ff"Ta5d6fftcp:192.168.1.1Ta5d6ff"Tb4b4b4) Tb4b4b4}
Te6edf3verify Tb4b4b4{ Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3setDeviceAddressTb4b4b4(Ta5d6ff"Ta5d6fftcp:192.168.1.1Ta5d6ff"Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetDeviceAddressSkipsSwitchWhenAddressUnchangedTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3meshPrefsTb4b4b4.Te6edf3deviceAddress Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Ta5d6ff"Ta5d6fftcp:192.168.1.1Ta5d6ff"Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setDeviceAddressTb4b4b4(Ta5d6ff"Ta5d6fftcp:192.168.1.1Ta5d6ff"Tb4b4b4)
Te6edf3testScopeTb4b4b4.Te6edf3advanceUntilIdleTb4b4b4(Tb4b4b4)
T8b949e// switchDevice should skip when addresses match, but transport still reconfigures
Te6edf3verify Tb4b4b4{ Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3setDeviceAddressTb4b4b4(Ta5d6ff"Ta5d6fftcp:192.168.1.1Ta5d6ff"Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3meshPrefsTb4b4b4.Te6edf3setDeviceAddressTb4b4b4(Ta5d6ff"Ta5d6fftcp:192.168.1.1Ta5d6ff"Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsendReactionPersistsToDatabaseTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!abcd1234Ta5d6ff"Tb4b4b4, Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffTestTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffTTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4, Te6edf3user Tff7b72= Te6edf3userTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNum Tb4b4b4} Te6edf3returns Te6edf3mapOfTb4b4b4(T79c0ff1T79c0ff2T79c0ff3T79c0ff4 Te6edf3to Te6edf3nodeTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3getMyIdTb4b4b4(Tb4b4b4) Tb4b4b4} Te6edf3returns Ta5d6ff"Ta5d6ff!abcd1234Ta5d6ff"
Te6edf3controllerTb4b4b4.Te6edf3sendReactionTb4b4b4(Te6edf3emoji Tff7b72= Ta5d6ff"Ta5d6ff👍Ta5d6ff"Tb4b4b4, Te6edf3replyId Tff7b72= T79c0ff4T79c0ff2Tb4b4b4, Te6edf3contactKey Tff7b72= Ta5d6ff"Ta5d6ff0!dest5678Ta5d6ff"Tb4b4b4)
T8b949e// Reaction must be persisted (not fire-and-forget)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendDataTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{ Te6edf3packetRepositoryTb4b4b4.Te6edf3insertReactionTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetFavoriteSendsAdminAndUpdatesStateTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff9T79c0ff9Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!node99Ta5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3isFavorite Tff7b72= Tff7b72falseTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNum Tb4b4b4} Te6edf3returns Te6edf3mapOfTb4b4b4(T79c0ff9T79c0ff9 Te6edf3to Te6edf3nodeTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setFavoriteTb4b4b4(T79c0ff9T79c0ff9Tb4b4b4, Te6edf3favorite Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verify Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3updateNodeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetFavoriteIsNoOpWhenAlreadyInRequestedStateTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff9T79c0ff9Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!node99Ta5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3isFavorite Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNum Tb4b4b4} Te6edf3returns Te6edf3mapOfTb4b4b4(T79c0ff9T79c0ff9 Te6edf3to Te6edf3nodeTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setFavoriteTb4b4b4(T79c0ff9T79c0ff9Tb4b4b4, Te6edf3favorite Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verifyTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3updateNodeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetIgnoredSendsAdminUpdatesStateAndFiltersPacketsTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff9T79c0ff9Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!node99Ta5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3isIgnored Tff7b72= Tff7b72falseTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNum Tb4b4b4} Te6edf3returns Te6edf3mapOfTb4b4b4(T79c0ff9T79c0ff9 Te6edf3to Te6edf3nodeTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setIgnoredTb4b4b4(T79c0ff9T79c0ff9Tb4b4b4, Te6edf3ignored Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3testScopeTb4b4b4.Te6edf3advanceUntilIdleTb4b4b4(Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verify Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3updateNodeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{ Te6edf3packetRepositoryTb4b4b4.Te6edf3updateFilteredBySenderTb4b4b4(Ta5d6ff"Ta5d6ff!node99Ta5d6ff"Tb4b4b4, Tff7b72trueTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8fftoggleMutedSendsAdminAndUpdatesStateTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff9T79c0ff9Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!node99Ta5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3isMuted Tff7b72= Tff7b72falseTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNum Tb4b4b4} Te6edf3returns Te6edf3mapOfTb4b4b4(T79c0ff9T79c0ff9 Te6edf3to Te6edf3nodeTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3toggleMutedTb4b4b4(T79c0ff9T79c0ff9Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verify Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3updateNodeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffnodeManagementReturnsEarlyWhenMyNodeNumIsNullTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3myNodeNum Tff7b72= Tff7b72nullTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setFavoriteTb4b4b4(T79c0ff9T79c0ff9Tb4b4b4, Te6edf3favorite Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setIgnoredTb4b4b4(T79c0ff9T79c0ff9Tb4b4b4, Te6edf3ignored Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3toggleMutedTb4b4b4(T79c0ff9T79c0ff9Tb4b4b4)
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffremoveByNodenumAlwaysRemovesLocallyAndSendsAdminWhenConnectedTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3removeByNodenumTb4b4b4(Te6edf3packetId Tff7b72= T79c0ff1Tb4b4b4, Te6edf3nodeNum Tff7b72= T79c0ff5T79c0ff5Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3removeByNodenumTb4b4b4(T79c0ff5T79c0ff5Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffremoveByNodenumRemovesLocallyEvenWhenDisconnectedTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3myNodeNum Tff7b72= Tff7b72nullTb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3removeByNodenumTb4b4b4(Te6edf3packetId Tff7b72= T79c0ff1Tb4b4b4, Te6edf3nodeNum Tff7b72= T79c0ff5T79c0ff5Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3removeByNodenumTb4b4b4(T79c0ff5T79c0ff5Tb4b4b4) Tb4b4b4}
T8b949e// No admin message sent when disconnected
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffrebootSendsAdminMessageWithDelayTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3rebootTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff1Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff7Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffshutdownSendsAdminMessageTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3shutdownTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff1Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff8Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8fffactoryResetSendsAdminMessageTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3factoryResetTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff1Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff9Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffnodedbResetSendsAdminMessageTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3nodedbResetTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff1Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff1T79c0ff0Tb4b4b4, Te6edf3preserveFavorites Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetTimeSendsAdminMessageWithCurrentEpochSecondsTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3sentMessageTb4b4b4: Te6edf3AdminMessage? Tff7b72= Tff7b72null
Te6edf3everySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffUNCHECKED_CASTTa5d6ff"Tb4b4b4)
Te6edf3sentMessage Tff7b72= Tb4b4b4(Tffa657itTb4b4b4.Te6edf3argsTff7b72[T79c0ff3Tff7b72] Tff7b72as Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3AdminMessageTb4b4b4)Tb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3controllerTb4b4b4.Te6edf3setTimeTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff1Tb4b4b4, Te6edf3packetId Tff7b72= T79c0ff1T79c0ff1Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
T8b949e// The phone's current time is sent; assert it is populated and a plausible recent epoch (after 2020).
Tff7b72val Te6edf3setTime Tff7b72= Te6edf3sentMessageTff7b72?.Te6edf3set_time_only
Te6edf3assertTrueTb4b4b4(Te6edf3setTime Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3setTime Tff7b72> T79c0ff1Te6edf3_577_836_800Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffrefreshMetadataSendsAdminWithWantResponseTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3refreshMetadataTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff1Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffeditLocalSettingsChannelWritesDoNotMirrorToLocalCacheTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3editLocalSettings Tb4b4b4{
Te6edf3setChannelTb4b4b4(Te6edf3ChannelTb4b4b4(Te6edf3index Tff7b72= T79c0ff0Tb4b4b4, Te6edf3role Tff7b72= Te6edf3ChannelTb4b4b4.Te6edf3RoleTb4b4b4.Te6edf3PRIMARYTb4b4b4, Te6edf3settings Tff7b72= Te6edf3ChannelSettingsTb4b4b4(Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffATa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3setChannelTb4b4b4(Te6edf3ChannelTb4b4b4(Te6edf3index Tff7b72= T79c0ff1Tb4b4b4, Te6edf3role Tff7b72= Te6edf3ChannelTb4b4b4.Te6edf3RoleTb4b4b4.Te6edf3SECONDARYTb4b4b4, Te6edf3settings Tff7b72= Te6edf3ChannelSettingsTb4b4b4(Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffBTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Te6edf3testScopeTb4b4b4.Te6edf3advanceUntilIdleTb4b4b4(Tb4b4b4)
T8b949e// Exactly 4 admin packets: begin + 2 channel writes + commit. The tight count also catches a duplicated
T8b949e// begin/commit or an accidental double-write per channel.
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
T8b949e// A transactional channel write must NOT eagerly mirror to the local cache the way one-shot
T8b949e// setRemoteChannel does for the local node. importChannelSet owns the cache and writes it once after commit
T8b949e// (replaceAllSettings), so an interrupted import can't leave partial channels cached. A regression to
T8b949e// per-slot mirroring inside the session would make this call count non-zero.
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3updateChannelSettingsTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffimportContactSendsAdminAndUpdatesNodeManagerTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
T8b949e// A scanned contact arrives with manually_verified = false (proto default).
Tff7b72val Te6edf3contact Tff7b72= Te6edf3SharedContactTb4b4b4(Te6edf3node_num Tff7b72= T79c0ff4T79c0ff2Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!0000002aTa5d6ff"Tb4b4b4, Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffTestTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72var Te6edf3sentMessageTb4b4b4: Te6edf3AdminMessage? Tff7b72= Tff7b72null
Te6edf3everySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffUNCHECKED_CASTTa5d6ff"Tb4b4b4)
Te6edf3sentMessage Tff7b72= Tb4b4b4(Tffa657itTb4b4b4.Te6edf3argsTff7b72[T79c0ff3Tff7b72] Tff7b72as Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3AdminMessageTb4b4b4)Tb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3controllerTb4b4b4.Te6edf3importContactTb4b4b4(Te6edf3contactTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
T8b949e// The verification state encoded by the sharer is honored as-is, not forced to true.
Te6edf3assertEqualsTb4b4b4(Tff7b72falseTb4b4b4, Te6edf3sentMessageTff7b72?.Te6edf3add_contactTff7b72?.Te6edf3manually_verifiedTb4b4b4)
Te6edf3verify Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedUserTb4b4b4(T79c0ff4T79c0ff2Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72falseTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffimportContactPreservesEncodedVerificationStateTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Tb4b4b4)
T8b949e// A contact shared as already verified stays verified on import.
Tff7b72val Te6edf3contact Tff7b72=
Te6edf3SharedContactTb4b4b4(Te6edf3node_num Tff7b72= T79c0ff4T79c0ff2Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!0000002aTa5d6ff"Tb4b4b4, Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffTestTa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3manually_verified Tff7b72= Tff7b72trueTb4b4b4)
Tff7b72var Te6edf3sentMessageTb4b4b4: Te6edf3AdminMessage? Tff7b72= Tff7b72null
Te6edf3everySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffUNCHECKED_CASTTa5d6ff"Tb4b4b4)
Te6edf3sentMessage Tff7b72= Tb4b4b4(Tffa657itTb4b4b4.Te6edf3argsTff7b72[T79c0ff3Tff7b72] Tff7b72as Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3AdminMessageTb4b4b4)Tb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3controllerTb4b4b4.Te6edf3importContactTb4b4b4(Te6edf3contactTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(Tff7b72trueTb4b4b4, Te6edf3sentMessageTff7b72?.Te6edf3add_contactTff7b72?.Te6edf3manually_verifiedTb4b4b4)
Te6edf3verify Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedUserTb4b4b4(T79c0ff4T79c0ff2Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Tff7b72trueTb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetHamModeSendsAdminWithEchoedLoraValuesAndUpdatesUserTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)
Tff7b72val Te6edf3existingUser Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!0000007bTa5d6ff"Tb4b4b4, Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffOld NameTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffOLDTa5d6ff"Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNum Tb4b4b4} Te6edf3returns Te6edf3mapOfTb4b4b4(T79c0ff1T79c0ff2T79c0ff3 Te6edf3to Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3existingUserTb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3localConfigFlow Tb4b4b4} Te6edf3returns
Te6edf3MutableStateFlowTb4b4b4(Te6edf3LocalConfigTb4b4b4(Te6edf3lora Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4(Te6edf3tx_power Tff7b72= T79c0ff2T79c0ff0Tb4b4b4, Te6edf3override_frequency Tff7b72= T79c0ff9T79c0ff1T79c0ff5.5fTb4b4b4)Tb4b4b4)Tb4b4b4)
Tff7b72var Te6edf3sentMessageTb4b4b4: Te6edf3AdminMessage? Tff7b72= Tff7b72null
Te6edf3everySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffUNCHECKED_CASTTa5d6ff"Tb4b4b4)
Te6edf3sentMessage Tff7b72= Tb4b4b4(Tffa657itTb4b4b4.Te6edf3argsTff7b72[T79c0ff3Tff7b72] Tff7b72as Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3AdminMessageTb4b4b4)Tb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3controllerTb4b4b4.Te6edf3setHamModeTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3HamParametersTb4b4b4(Te6edf3call_sign Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4)Tb4b4b4, T79c0ff4T79c0ff2Tb4b4b4)
Tff7b72val Te6edf3ham Tff7b72= Te6edf3sentMessageTff7b72?.Te6edf3set_ham_mode
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3hamTff7b72?.Te6edf3call_signTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4, Te6edf3hamTff7b72?.Te6edf3short_nameTb4b4b4)
T8b949e// Current LoRa values are echoed so a re-send never wipes the node's overrides.
Te6edf3assertEqualsTb4b4b4(T79c0ff2T79c0ff0Tb4b4b4, Te6edf3hamTff7b72?.Te6edf3tx_powerTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff9T79c0ff1T79c0ff5.5fTb4b4b4, Te6edf3hamTff7b72?.Te6edf3frequencyTb4b4b4)
Te6edf3verify Tb4b4b4{
Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedUserTb4b4b4(
T79c0ff1T79c0ff2T79c0ff3Tb4b4b4,
Te6edf3existingUserTb4b4b4.Te6edf3copyTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4, Te6edf3is_licensed Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4,
T79c0ff0Tb4b4b4,
Tff7b72falseTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetHamModeWithNoCachedLoraConfigSendsProtoDefaultsTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3nodeDBbyNodeNum Tb4b4b4} Te6edf3returns Te6edf3emptyMapTb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3localConfigFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3LocalConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72var Te6edf3sentMessageTb4b4b4: Te6edf3AdminMessage? Tff7b72= Tff7b72null
Te6edf3everySuspend Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffUNCHECKED_CASTTa5d6ff"Tb4b4b4)
Te6edf3sentMessage Tff7b72= Tb4b4b4(Tffa657itTb4b4b4.Te6edf3argsTff7b72[T79c0ff3Tff7b72] Tff7b72as Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3AdminMessageTb4b4b4)Tb4b4b4(Tb4b4b4)
Tb4b4b4}
Te6edf3controllerTb4b4b4.Te6edf3setHamModeTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3HamParametersTb4b4b4(Te6edf3call_sign Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4)Tb4b4b4, T79c0ff4T79c0ff2Tb4b4b4)
Tff7b72val Te6edf3ham Tff7b72= Te6edf3sentMessageTff7b72?.Te6edf3set_ham_mode
Te6edf3assertEqualsTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3hamTff7b72?.Te6edf3tx_powerTb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff0fTb4b4b4, Te6edf3hamTff7b72?.Te6edf3frequencyTb4b4b4)
T8b949e// Unknown node: the optimistic update is built on a default User.
Te6edf3verify Tb4b4b4{
Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedUserTb4b4b4(
T79c0ff1T79c0ff2T79c0ff3Tb4b4b4,
Te6edf3UserTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4, Te6edf3is_licensed Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4,
T79c0ff0Tb4b4b4,
Tff7b72falseTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffsetHamModeIgnoresRemoteDestinationsTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3setHamModeTb4b4b4(T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Te6edf3HamParametersTb4b4b4(Te6edf3call_sign Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4)Tb4b4b4, T79c0ff4T79c0ff2Tb4b4b4)
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verifyTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3nodeManagerTb4b4b4.Te6edf3handleReceivedUserTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ffimportContactReturnsEarlyWhenDisconnectedTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3controller Tff7b72= Te6edf3createControllerTb4b4b4(Te6edf3myNodeNum Tff7b72= Tff7b72nullTb4b4b4)
Tff7b72val Te6edf3contact Tff7b72= Te6edf3SharedContactTb4b4b4(Te6edf3node_num Tff7b72= T79c0ff4T79c0ff2Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!0000002aTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3controllerTb4b4b4.Te6edf3importContactTb4b4b4(Te6edf3contactTb4b4b4)
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3commandSenderTb4b4b4.Te6edf3sendAdminTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.2 - Generated in 0.23s